/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package net.alteiar.plateform.gui;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.concurrent.TimeUnit;

import net.alteiar.plateform.game.SystemTimer;
import net.alteiar.plateform.game.World;
import net.alteiar.plateform.game.view.UiWorld;

/**
 * @author Cody Stoutenburg
 * 
 */
public class RunnableUi implements Runnable, KeyListener {
	private final boolean gameRunning;

	private final WorldCanevas canevas;
	private final UiWorld world;

	private final long frameWaitDuration;

	private boolean leftPressed;
	private boolean rightPressed;
	private boolean upPressed;
	private boolean downPressed;

	// stat info
	private final boolean showStat;
	private long showCount;
	private long beginTime;

	public RunnableUi(World world, long fps) {
		showStat = true;
		showCount = 0;

		gameRunning = true;

		leftPressed = false;
		rightPressed = false;
		upPressed = false;
		downPressed = false;

		this.frameWaitDuration = SystemTimer.getTimeUnit().convert(1,
				TimeUnit.SECONDS)
				/ fps;

		this.world = new UiWorld(world, TimeUnit.MILLISECONDS.convert(
				this.frameWaitDuration, SystemTimer.getTimeUnit()));

		MainFrame frame = new MainFrame(this.world.getVisiblePixelWidth(),
				this.world.getVisiblePixelHeight());
		frame.setVisible(true);
		canevas = frame.getCanevas();
		canevas.addKeyListener(this);
	}

	@Override
	public void run() {
		/** The stragey that allows us to use accelerate page flipping */
		BufferStrategy strategy = canevas.getBufferStrategy();

		long currentLoopTime = 0;

		beginTime = SystemTimer.getTime();

		// keep looping round til the game ends
		while (gameRunning) {
			// work out how long its been since the last update, this
			// will be used to calculate how far the entities should
			// move this loop
			currentLoopTime = SystemTimer.getTime();

			// Get hold of a graphics context for the accelerated
			// surface and blank it out
			Graphics2D g = (Graphics2D) strategy.getDrawGraphics();

			if (leftPressed) {
				moveX(-5);
			} else if (rightPressed) {
				moveX(5);
			}

			if (downPressed) {
				moveY(5);
			} else if (upPressed) {
				moveY(-5);
			}
			world.draw(g);

			if (showStat) {
				double fps = 0;
				if (showCount > 0) {
					long oneSec = SystemTimer.getTimeUnit().convert(1L,
							TimeUnit.SECONDS);
					fps = oneSec / ((currentLoopTime - beginTime) / showCount);
				}
				String fpsString = "fps moyen: " + fps;

				Font f = g.getFont();
				f = f.deriveFont(20.0f);
				f = f.deriveFont(Font.BOLD);
				g.setFont(f);

				g.drawString(fpsString, 500, 20);
				showCount++;
			}

			// cycle round drawing all the entities we have in the game
			// for (int i = 0; i < entities.size(); i++) {
			// Entity entity = (Entity) entities.get(i);

			// entity.draw(g);
			// }

			// if we're waiting for an "any key" press then draw the
			// current message
			// if (waitingForKeyPress) {
			// g.setColor(Color.white);
			// g.drawString(message,
			// (800 - g.getFontMetrics().stringWidth(message)) / 2,
			// 250);
			// g.drawString("Press any key", (800 - g.getFontMetrics()
			// .stringWidth("Press any key")) / 2, 300);
			// }

			// finally, we've completed drawing so clear up the graphics
			// and flip the buffer over
			g.dispose();
			strategy.show();

			// finally pause for a bit.
			SystemTimer.sleep(currentLoopTime, frameWaitDuration);
		}
	}

	public void moveX(int x) {
		world.move(x, 0);
	}

	public void moveY(int y) {
		world.move(0, y);
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_LEFT) {
			leftPressed = true;
		}
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
			rightPressed = true;
		}

		if (e.getKeyCode() == KeyEvent.VK_DOWN) {
			downPressed = true;
		}
		if (e.getKeyCode() == KeyEvent.VK_UP) {
			upPressed = true;
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_LEFT) {
			leftPressed = false;
		}
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
			rightPressed = false;
		}
		if (e.getKeyCode() == KeyEvent.VK_DOWN) {
			downPressed = false;
		}
		if (e.getKeyCode() == KeyEvent.VK_UP) {
			upPressed = false;
		}
	}
}
